package rr18.rr181.rr181.rr18.operate;

import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.AddValidatorsEventArgs;
import kd.bos.entity.plugin.PreparePropertysEventArgs;
import kd.bos.entity.plugin.args.*;
import kd.bos.entity.validate.AbstractValidator;
import kd.bos.entity.validate.ErrorLevel;
import kd.bos.entity.validate.ValidationErrorInfo;
import kd.bos.exception.KDException;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import kd.bos.servicehelper.workflow.MessageCenterServiceHelper;
import kd.bos.workflow.engine.msg.info.MessageInfo;
import kd.bos.workflow.message.service.MessageCenterService;
import kd.sdk.plugin.Plugin;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 单据操作插件
 */
public class ReqOppSubmitServicePlugin extends AbstractOperationServicePlugIn implements Plugin {

    //插件中要get或者set使用的字段，要先在本事件中预添加（加载）
    @Override
    public void onPreparePropertys(PreparePropertysEventArgs e) {
        //加载“采购方式”字段
        e.getFieldKeys().add("kdec_buyway");
        //加载“采购单价”字段
        e.getFieldKeys().add("kdec_pricefield");
        e.getFieldKeys().add("kdec_currencyfield");
        e.getFieldKeys().add("kdec_company");
    }
    /**
     * 执行操作校验前，触发此事件
     * @remark
     * 插件可以在此事件，调整预置的操作校验器；或者增加自定义操作校验器
     */
    @Override
    public void onAddValidators(AddValidatorsEventArgs e) {
        //添加自定义的校验器：
        e.addValidator(new ReqSubmitValidator());
    }

    private class ReqSubmitValidator extends AbstractValidator {

        @Override
        public void validate() {
            for (ExtendedDataEntity extendedDataEntity : this.getDataEntities()) {
                DynamicObject dataEntity = extendedDataEntity.getDataEntity();
                DynamicObjectCollection entrys = dataEntity.getDynamicObjectCollection("kdec_reqentryentity");
                StringBuilder strbd = new StringBuilder();
                    for (int i = 0; i < entrys.size(); i++) {
                        //各分录行数据
                        DynamicObject entryObj = entrys.get(i);
                        BigDecimal price = entryObj.getBigDecimal("kdec_pricefield");
                        int reqWay = entryObj.getInt("kdec_buyway");
                        //采购方式为自费时，采购单价不能小于0
                        if (reqWay == 1 && price.compareTo(BigDecimal.ZERO) < 1) {
                            strbd.append(i + 1);
                            strbd.append("、");
                        }
                    }
                    if (strbd.length() > 0) {
                        strbd.deleteCharAt(strbd.length() - 1);
                        //提示校验失败，终止提交操作
                        this.addErrorMessage(extendedDataEntity, String.format("操作插件校验：第%s行采购方式为自费时，采购单价不能小于0!", strbd.toString()));
                    }
            }
        }
    }
//操作校验通过之后，开启事务之前，触发此事件；
    @Override
    public void beforeExecuteOperationTransaction(BeforeOperationArgs e) {
        if (e.getOperationKey().equals("submit")) {
            List<ExtendedDataEntity> passDataEntitys = new ArrayList<>();
            List<ExtendedDataEntity> validExtDataEntities = e.getValidExtDataEntities();
            for (ExtendedDataEntity extendedDataEntity : validExtDataEntities) {
                DynamicObject doj = extendedDataEntity.getDataEntity();
                //使用的字段必须要在onPreparePropertys中注册
                if (doj.getDynamicObject("kdec_currencyfield").get("number").equals("CNY")) {
                    passDataEntitys.add(extendedDataEntity);
                } else {
                    Object pkId = doj.getPkValue();
                    int rowIndex = 0;
                    ErrorLevel errorLevel = ErrorLevel.Error;
                    ValidationErrorInfo errInfo = new ValidationErrorInfo("",
                            pkId, 1, 2,
                            "BeforeExecuteOperationTransactionSample",
                            "送货日期检查",
                            "beforeExecuteOperationTransaction：币别只能是人民币",
                            errorLevel);

                    this.operationResult.addErrorInfo(errInfo);
                }
            }
            if (passDataEntitys.size() == 0) {
                e.setCancel(true);
            } else {
                e.getValidExtDataEntities().clear();
                e.getValidExtDataEntities().addAll(passDataEntitys);
            }
        }
        super.beforeExecuteOperationTransaction(e);
    }

    @Override
    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
        if (e.getOperationKey().equals("submit")) {
            DynamicObject[] dataEntities1 = e.getDataEntities();
            for (int index = 0; index < dataEntities1.length; index++) {
                if (index == 1) {//没有在onPreparePropertys中添加要使用的字段，会抛异常，并触发事务回滚，所有数据都会提交失败
                    dataEntities1[1].get("kdec_company");
                }
            }
        }
        super.beginOperationTransaction(e);
    }

    @Override
    public void endOperationTransaction(EndOperationTransactionArgs e) {
        if (e.getOperationKey().equals("submit")) {
            DynamicObject[] dataEntities1 = e.getDataEntities();
            ArrayList<DynamicObject> logs = new ArrayList<>();
            for (int index = 0; index < dataEntities1.length; index++) {
                //提交之后，同步记录采购申请单的操作记录
                DynamicObject kdecMylog = BusinessDataServiceHelper.newDynamicObject("kdec_mylog");
                kdecMylog.set("billno",dataEntities1[index].getPkValue());
                logs.add(kdecMylog);
            }
//            单据状态字段是必录的，但是没赋值，就保存了
            OperationResult result = SaveServiceHelper.saveOperate("save", "kdec_mylog", logs.toArray(new DynamicObject[logs.size()]), OperateOption.create());
            if (!result.isSuccess()){
//                throw new KDException("记录日志失败");//记录日志失败时，抛异常去触发事务回滚，让单据同步提交失败
            }
        }
        super.endOperationTransaction(e);
    }

    @Override
    public void rollbackOperation(RollbackOperationArgs e) {
        //事务异常的数据
        DynamicObject[] dataEntitys = e.getDataEntitys();
        MessageInfo messageInfo = new MessageInfo();
        messageInfo.setType(MessageInfo.TYPE_WARNING);
        ArrayList<Long> recevivers = new ArrayList<>();
        recevivers.add(UserServiceHelper.getCurrentUserId());
        messageInfo.setUserIds(recevivers);
        messageInfo.setSenderName("系统发送");
        messageInfo.setSenderId(UserServiceHelper.getCurrentUserId());
        messageInfo.setEntityNumber("kdec_reqbill");
        messageInfo.setOperation("submit");
        messageInfo.setTag("提交异常");
        messageInfo.setPubaccNumber("flowassist");
        messageInfo.setContent("采购申请单提交异常");
        MessageCenterServiceHelper.sendMessage(messageInfo);
        super.rollbackOperation(e);
    }

    @Override
    public void afterExecuteOperationTransaction(AfterOperationArgs e) {
        if (e.getOperationKey().equals("submit")) {
            DynamicObject[] dataEntities1 = e.getDataEntities();
            ArrayList<DynamicObject> logs = new ArrayList<>();
            for (int index = 0; index < dataEntities1.length; index++) {
                //提交之后，同步记录采购申请单的操作记录
                DynamicObject kdecMylog = BusinessDataServiceHelper.newDynamicObject("kdec_mylog");
                kdecMylog.set("billno",dataEntities1[index].getPkValue());
                logs.add(kdecMylog);
            }
//            单据状态字段是必录的，但是没赋值，就保存了
            OperationResult result = SaveServiceHelper.saveOperate("save", "kdec_mylog", logs.toArray(new DynamicObject[logs.size()]), OperateOption.create());
            if (!result.isSuccess()){
                throw new KDException("afterExecuteOperationTransaction记录日志失败");
            }
        }
        super.afterExecuteOperationTransaction(e);
    }
}